package system

import (
	"encoding/json"
	"log"
	"server/config"
	"server/plugin/db"
)

// Category 分类信息
type Category struct {
	Id   int64  `json:"id" gorm:"primaryKey;autoIncrement"` // 分类ID
	Pid  int64  `json:"pid"`                                // 父级分类ID
	Name string `json:"name"`                               // 分类名称
	Show bool   `json:"show"`                               // 是否展示
}

// TableName 指定表名
func (Category) TableName() string {
	return "category"
}

// CategoryTree 分类信息树形结构
type CategoryTree struct {
	*Category
	Children []*CategoryTree `json:"children"` // 子分类信息
}

// 影视分类展示树形结构1111

// SaveCategoryTree 保存影片分类信息（同时保存到数据库和缓存）
func SaveCategoryTree(tree *CategoryTree) error {
	// 先保存到数据库
	if err := saveCategoryTreeToDB(tree); err != nil {
		log.Println("SaveCategoryTree to DB Error:", err)
		return err
	}

	// 再保存到缓存
	data, _ := json.Marshal(tree)
	return db.Rdb.Set(db.Cxt, config.CategoryTreeKey, data, config.FilmExpired).Err()
}

// GetCategoryTree 获取影片分类信息（优先从缓存获取，缓存没有则从数据库获取并更新缓存）
func GetCategoryTree() CategoryTree {
	// 先从缓存获取
	data := db.Rdb.Get(db.Cxt, config.CategoryTreeKey).Val()
	tree := CategoryTree{}

	if data != "" {
		// 缓存中有数据，直接返回
		_ = json.Unmarshal([]byte(data), &tree)
		return tree
	}

	// 缓存中没有数据，从数据库获取并构建树形结构
	roots, err := GetCategoryTreeFromDB()
	if err != nil {
		log.Println("GetCategoryTree from DB Error:", err)
		return tree
	}

	// 如果数据库中有数据，构建完整的树形结构并更新缓存
	if len(roots) > 0 {
		// 这里假设只有一个根节点，如果有多个根节点需要调整逻辑
		if len(roots) == 1 {
			tree = *roots[0]
		} else {
			// 多个根节点的情况，创建一个虚拟根节点
			tree = CategoryTree{
				Category: &Category{Id: 0, Name: "root"},
				Children: roots,
			}
		}

		// 更新缓存
		treeData, _ := json.Marshal(tree)
		db.Rdb.Set(db.Cxt, config.CategoryTreeKey, treeData, config.FilmExpired)
	}

	return tree
}

// ExistsCategoryTree 查询分类信息是否存在（优先检查缓存，缓存没有则检查数据库并更新缓存）
func ExistsCategoryTree() bool {
	// 先检查缓存
	exists, err := db.Rdb.Exists(db.Cxt, config.CategoryTreeKey).Result()
	if err != nil {
		log.Println("ExistsCategoryTree Redis Error", err)
	}

	if exists == 1 {
		return true
	}

	var count int64
	// 缓存中没有，检查数据库
	err = db.Mdb.Model(&Category{}).Count(&count).Error
	if err != nil {
		log.Println("ExistsCategoryTree DB Error", err)
		return false
	}

	// 如果数据库中有数据，重新构建缓存
	if count > 0 {
		tree := GetCategoryTree() // 这会从数据库加载并更新缓存
		return tree.Category != nil
	}

	return false
}

// GetChildrenTree 根据影片Id获取对应分类的子分类信息
func GetChildrenTree(id int64) []*CategoryTree {
	tree := GetCategoryTree()
	for _, t := range tree.Children {
		if t.Id == id {
			return t.Children
		}
	}
	return nil
}

// ==================== 数据库持久化操作 ====================

// CreateCategory 创建分类
func CreateCategory(category *Category) error {
	return db.Mdb.Create(category).Error
}

// GetCategoryById 根据ID获取分类
func GetCategoryById(id int64) (*Category, error) {
	var category Category
	err := db.Mdb.Where("id = ?", id).First(&category).Error
	return &category, err
}

// GetCategoriesByPid 根据父级ID获取子分类列表
func GetCategoriesByPid(pid int64) ([]*Category, error) {
	var categories []*Category
	err := db.Mdb.Where("pid = ?", pid).Find(&categories).Error
	return categories, err
}

// GetAllCategories 获取所有分类
func GetAllCategories() ([]*Category, error) {
	var categories []*Category
	err := db.Mdb.Find(&categories).Error
	return categories, err
}

// UpdateCategory 更新分类信息
func UpdateCategory(category *Category) error {
	return db.Mdb.Save(category).Error
}

// DeleteCategory 删除分类
func DeleteCategory(id int64) error {
	return db.Mdb.Where("id = ?", id).Delete(&Category{}).Error
}

// DeleteCategoryAndChildren 删除分类及其所有子分类
func DeleteCategoryAndChildren(id int64) error {
	// 递归删除所有子分类
	children, err := GetCategoriesByPid(id)
	if err != nil {
		return err
	}

	for _, child := range children {
		if err := DeleteCategoryAndChildren(child.Id); err != nil {
			return err
		}
	}

	// 删除当前分类
	return DeleteCategory(id)
}

// GetCategoryTreeFromDB 从数据库构建分类树
func GetCategoryTreeFromDB() ([]*CategoryTree, error) {
	categories, err := GetAllCategories()
	if err != nil {
		return nil, err
	}

	// 构建分类映射
	categoryMap := make(map[int64]*CategoryTree)
	var roots []*CategoryTree

	// 创建所有节点
	for _, category := range categories {
		tree := &CategoryTree{
			Category: category,
			Children: make([]*CategoryTree, 0),
		}
		categoryMap[category.Id] = tree
	}

	// 构建树形结构
	for _, category := range categories {
		if category.Pid == 0 {
			// 根节点
			roots = append(roots, categoryMap[category.Id])
		} else {
			// 子节点
			if parent, exists := categoryMap[category.Pid]; exists {
				parent.Children = append(parent.Children, categoryMap[category.Id])
			}
		}
	}

	return roots, nil
}

// GetVisibleCategories 获取显示状态的分类
func GetVisibleCategories() ([]*Category, error) {
	var categories []*Category
	err := db.Mdb.Where("show = ?", true).Find(&categories).Error
	return categories, err
}

// UpdateCategoryShow 更新分类显示状态
func UpdateCategoryShow(id int64, show bool) error {
	return db.Mdb.Model(&Category{}).Where("id = ?", id).Update("show", show).Error
}

// BatchCreateCategories 批量创建分类
func BatchCreateCategories(categories []*Category) error {
	return db.Mdb.CreateInBatches(categories, 100).Error
}

// CountCategoriesByPid 统计指定父级下的分类数量
func CountCategoriesByPid(pid int64) (int64, error) {
	var count int64
	err := db.Mdb.Model(&Category{}).Where("pid = ?", pid).Count(&count).Error
	return count, err
}

// ==================== 缓存和数据库同步操作 ====================

// saveCategoryTreeToDB 将分类树保存到数据库（递归保存）
func saveCategoryTreeToDB(tree *CategoryTree) error {
	if tree == nil || tree.Category == nil {
		return nil
	}

	// 保存当前节点
	if err := db.Mdb.Save(tree.Category).Error; err != nil {
		return err
	}

	// 递归保存子节点
	for _, child := range tree.Children {
		if err := saveCategoryTreeToDB(child); err != nil {
			return err
		}
	}

	return nil
}

// CreateCategoryWithCache 创建分类并清除缓存
func CreateCategoryWithCache(category *Category) error {
	// 创建分类
	if err := CreateCategory(category); err != nil {
		return err
	}

	// 清除缓存，下次获取时会重新从数据库构建
	clearCategoryCache()
	return nil
}

// UpdateCategoryWithCache 更新分类并清除缓存
func UpdateCategoryWithCache(category *Category) error {
	// 更新分类
	if err := UpdateCategory(category); err != nil {
		return err
	}

	// 清除缓存
	clearCategoryCache()
	return nil
}

// DeleteCategoryWithCache 删除分类并清除缓存
func DeleteCategoryWithCache(id int64) error {
	// 删除分类
	if err := DeleteCategory(id); err != nil {
		return err
	}

	// 清除缓存
	clearCategoryCache()
	return nil
}

// DeleteCategoryAndChildrenWithCache 删除分类及其子分类并清除缓存
func DeleteCategoryAndChildrenWithCache(id int64) error {
	// 删除分类及其子分类
	if err := DeleteCategoryAndChildren(id); err != nil {
		return err
	}

	// 清除缓存
	clearCategoryCache()
	return nil
}

// UpdateCategoryShowWithCache 更新分类显示状态并清除缓存
func UpdateCategoryShowWithCache(id int64, show bool) error {
	// 更新显示状态
	if err := UpdateCategoryShow(id, show); err != nil {
		return err
	}

	// 清除缓存
	clearCategoryCache()
	return nil
}

// BatchCreateCategoriesWithCache 批量创建分类并清除缓存
func BatchCreateCategoriesWithCache(categories []*Category) error {
	// 批量创建分类
	if err := BatchCreateCategories(categories); err != nil {
		return err
	}

	// 清除缓存
	clearCategoryCache()
	return nil
}

// clearCategoryCache 清除分类缓存
func clearCategoryCache() {
	err := db.Rdb.Del(db.Cxt, config.CategoryTreeKey).Err()
	if err != nil {
		log.Println("Clear category cache error:", err)
	}
}

// RefreshCategoryCache 刷新分类缓存（从数据库重新加载）
func RefreshCategoryCache() error {
	// 先清除缓存
	clearCategoryCache()

	// 重新获取分类树（这会从数据库加载并更新缓存）
	tree := GetCategoryTree()

	// 检查是否成功加载
	if tree.Category == nil {
		return nil // 数据库中没有数据，这是正常情况
	}

	return nil
}
